package pl.edu.pw.elka.dzielins.revanalyzer;

import java.util.UUID;

import pl.edu.pw.elka.dzielins.revanalyzer.instance.Instance;
import pl.edu.pw.elka.dzielins.revanalyzer.instance.InstanceObject;
import pl.edu.pw.elka.dzielins.revanalyzer.instance.InstanceRelation;
import pl.edu.pw.elka.dzielins.revanalyzer.model.ModelRelation;

public class GraphUtil {
	private static final String[] colors = {
		"aliceblue",
		"antiquewhite",
		"aqua",
		"aquamarine",
		"azure",
		"beige",
		"bisque",
		"black, fontcolor=white",
		"blanchedalmond",
		"blue",
		"blueviolet",
		"brown",
		"burlywood",
		"cadetblue",
		"chartreuse",
		"chocolate",
		"coral",
		"cornflowerblue>",
		"cornsilk",
		"crimson",
		"cyan",
		"darkblue",
		"darkcyan",
		"darkgoldenrod",
		"darkgray",
		"darkgreen, fontcolor=white",
		"darkgrey",
		"darkkhaki",
		"darkmagenta",
		"darkolivegreen, fontcolor=white",
		"darkorange",
		"darkorchid",
		"darkred",
		"darksalmon",
		"darkseagreen",
		"darkslateblue",
		"darkslategray, fontcolor=white",
		"darkslategrey, fontcolor=white",
		"darkturquoise",
		"darkviolet",
		"deeppink",
		"deepskyblue",
		"dimgray, fontcolor=white",
		"dimgrey, fontcolor=white",
		"dodgerblue",
		"firebrick",
		"floralwhite",
		"forestgreen",
		"fuchsia",
		"gainsboro",
		"ghostwhite",
		"gold",
		"goldenrod",
		"gray, fontcolor=white",
		"grey, fontcolor=white",
		"green, fontcolor=white",
		"greenyellow",
		"honeydew",
		"hotpink",
		"indianred",
		"indigo, fontcolor=white",
		"ivory",
		"khaki",
		"lavender",
		"lavenderblush",
		"lawngreen",
		"lemonchiffon",
		"lightblue",
		"lightcoral",
		"lightcyan",
		"lightgoldenrodyellow",
		"lightgray",
		"lightgreen",
		"lightgrey",
		"lightpink",
		"lightsalmon",
		"lightseagreen",
		"lightskyblue",
		"lightslategray",
		"lightslategrey",
		"lightsteelblue",
		"lightyellow",
		"lime",
		"limegreen",
		"linen",
		"magenta",
		"maroon, fontcolor=white",
		"mediumaquamarine",
		"mediumblue",
		"mediumorchid",
		"mediumpurple",
		"mediumseagreen",
		"mediumslateblue",
		"mediumspringgreen",
		"mediumturquoise",
		"mediumvioletred",
		"midnightblue, fontcolor=white",
		"mintcream",
		"mistyrose",
		"moccasin",
		"navajowhite",
		"navy, fontcolor=white",
		"oldlace",
		"olive, fontcolor=white",
		"olivedrab",
		"orange",
		"orangered",
		"orchid",
		"palegoldenrod",
		"palegreen",
		"paleturquoise",
		"palevioletred",
		"papayawhip",
		"peachpuff",
		"peru",
		"pink",
		"plum",
		"powderblue",
		"purple, fontcolor=white",
		"red",
		"rosybrown",
		"royalblue",
		"saddlebrown",
		"salmon",
		"sandybrown",
		"seagreen",
		"seashell",
		"sienna",
		"silver",
		"skyblue",
		"slateblue",
		"slategray",
		"slategrey",
		"snow",
		"springgreen",
		"steelblue",
		"tan",
		"teal, fontcolor=white",
		"thistle",
		"tomato",
		"turquoise",
		"violet",
		"wheat",
		"white",
		"whitesmoke",
		"yellow",
		"yellowgreen"		
	};
	private static final String[] shapes = {
		"box",
		"ellipse",
		"circle",
		"egg",
		"triangle",
		"diamond",
		"trapezium",
		"parallelogram",
		"house",
		"hexagon",
		"octagon",
		"invtriangle",
		"invtrapezium",
		"invhouse",
		"septagon"
	};
	
	public static String dotGraph(Instance instance) {
		StringBuilder sb = new StringBuilder();
		sb.append("digraph G {");
		for (InstanceObject io : instance.getObjects()) {
			long l = io.getBaseObject().getName().hashCode();
			sb.append(io.getName());
			sb.append("[style=filled,");
			sb.append(getColor(l));
			sb.append(",");
			sb.append(getShape(l));
			sb.append("]");
			sb.append(";");
		}
		for (InstanceObject io : instance.getObjects()) {
			if (io.getRelations() == null || io.getRelations().isEmpty())
				continue;
			for (ModelRelation mr : io.getRelations().keySet()) {
				for (InstanceRelation ir : io.getRelations().get(mr)) {
					if (ir.getArguments().size() > 1) {
						String relationCrossName = io.getName()+"_"+mr.getName()+"_"+UUID.randomUUID();
						sb.append(relationCrossName);
						sb.append("[shape=point,label=\"\"];");
						sb.append(io.getName());
						sb.append(" -> ");
						sb.append(relationCrossName);
						for (InstanceObject relationArgument : ir.getArguments()) {
							sb.append(relationCrossName);
							sb.append(" -> ");
							sb.append(relationArgument.getName());
							sb.append(";");
						}
					} else {
						sb.append(io.getName());
						sb.append(" -> ");
						sb.append(ir.getArguments().get(0).getName());
						sb.append(";");
					}
				}
			}
		}
		sb.append("}");
		return sb.toString();
	}
	
	private static String getColor(long l) {
		return "color="+colors[(int) (l%colors.length)];
	}
	
	private static String getShape(long l) {
		return "shape="+shapes[(int) (l%shapes.length)];
	}
}
